//////////////////////////////////////////////////////////////////////
//                                                                  //
//                                                                  //
//              Copyright (C), 2000  SEIKO EPSON Corp.              //
//              ALL RIGHTS RESERVED                                 //
//                                                                  //
//                                                                  //
//   file name : frexp.c                                            //
//                                                                  //
//   Revision history                                               //
//       00/02/10    first release                 M.Igarashi       //
//                                                                  //
//////////////////////////////////////////////////////////////////////

#include <smcvals.h>
#include <math.h>

// ALGORITHM
// 1.get the fraction part as xfrac and exponent part as xexp from the argument
// 2.not xexp 0 then mask 0x800fffff
// 3.set exponent of iXfrac
//

//  the architecture of double floating point
//
//   0 1          11                  31 32                               63bit
//   -----------------------------------------------------------------------
//  | |   exponent  |                    fraction                           |
//   -----------------------------------------------------------------------
//  |               |                   |                                   |
//  |     12bits          20 bits       |             32 bits               |
//  |            lower word             |            higher word            |
//
//         bit    0         sign bit         (  1 bit  )
//              1 - 11      exponent part    ( 11 bits )
//             12 - 63      fraction part    ( 52 bits )
//
//

double	frexp(double dfX,int *iX2){

	DBL_LNG	xfrac;
	unsigned long	ulLl;
	unsigned long	ulLh;
	int		iXexp;
	unsigned long	ulLflg;
	double dfRet;

	xfrac._D=dfX;
	ulLh=xfrac.st._LH;
	ulLl=xfrac.st._LL;

	iXexp=GET_EXP(ulLl);		// get expo 1-11

	ulLflg=GET_HI_FRAC(ulLl);	// get frac 12-31
	
	if((iXexp==0)&&(ulLflg==0)&&(GET_LO_FRAC(ulLh)==0)){		//	x==0
		*iX2=0;
		dfRet=xfrac._D;
		return dfRet;
	}

	*iX2=iXexp-B_DBL+1;
	iXexp=B_DBL-1;
	ulLl=EXP_PUT(MASK_EXPO(ulLl),iXexp);		//	set fraction 
	xfrac.st._LL=ulLl;

	dfRet=xfrac._D;
	return dfRet;
}
